/*
 * @Author: soso
 * @Date: 2022-02-15 01:58:04
 * @LastEditTime: 2022-03-14 15:05:34
 * @LastEditors: Please set LastEditors
 * @Description: 配置文件
 * @FilePath: /gomeshcli/sconfig/sconfig.go
 */
package sconfig

import (
	"errors"
	"io/ioutil"
	"net"
	"os"
	"path/filepath"
	"strconv"

	"gitee.com/kimsoso/go-utils/utils"
	"gopkg.in/yaml.v3"
)

type sconfig struct {
	WatchDir   string `yaml:"watchDir"`
	RemoteHost string `yaml:"remoteHost"`
	HttpPort   int    `yaml:"httpPort"`
	Port       uint   `yaml:"port"`
	Log        bool   `yaml:"log"`
}

var (
	scpath = filepath.Join(utils.GetCurrentAbPath(), "c.yaml")

	SConfig = NewSConfig()
)

func init() {
	setLog()
}

func NewSConfig() *sconfig {
	sc := &sconfig{}
	sc.load()
	sc.check()
	return sc
}

func (sc *sconfig) check() {
	if sc.WatchDir == "" {
		panic("请设置监测目录")
	}

	curPath := utils.GetCurrentAbPath()

	// 处理相对路径的问题
	if !filepath.IsAbs(sc.WatchDir) {
		sc.WatchDir = filepath.Join(curPath, sc.WatchDir)
	}

	fi, err := os.Stat(sc.WatchDir)
	if os.IsNotExist(err) || !fi.IsDir() {
		panic("监测目录不存在")
	}

	if sc.RemoteHost == "" {
		panic("请设置远程节点")
	}

	if net.ParseIP(sc.RemoteHost) == nil {
		panic("远程节点IP设置不正确")
	}

	if sc.Port == 0 {
		panic("远程节点端口设置不正确")
	}
}

// 设置监视目录
func (sc *sconfig) SetWatchDir(dir string) error {
	_, err := os.Stat(dir)
	if err != nil {
		return err
	}
	sc.WatchDir = dir
	sc.save()
	return nil
}

// 设置远程节点
func (sc *sconfig) SetRemoteHost(host string, port int) error {
	netip := net.ParseIP(host)
	if netip == nil {
		return errors.New("不是一个有效的IP地址")
	}
	sc.RemoteHost = host + ":" + strconv.Itoa(port)
	sc.save()
	return nil
}

// 加载配置文件
func (sc *sconfig) load() {
	buf, err := ioutil.ReadFile(scpath)
	if err == nil {
		yaml.Unmarshal(buf, sc)
	} else {
		sc.WatchDir = "files/"
		sc.RemoteHost = ""
	}
}

// 保存配置到磁盘文件
func (sc *sconfig) save() {
	buf, err := yaml.Marshal(sc)
	if err == nil && len(buf) > 0 {
		ioutil.WriteFile(scpath, buf, os.ModePerm)
	}
}

func (sc *sconfig) GetHostPort() string {
	return sc.RemoteHost + ":" + strconv.Itoa(int(sc.Port))
}
